2023/12/232479字符
Proxy 代理
Proxy 代理(中介公司)
数据更改
const obj = {
a: 1,
b: 2
}
const proxy = new Proxy(obj, {});
proxy.a = 10;
console.log(proxy); //--> Proxy {a: 10, b: 2}
set重写
const obj = {
a: 10,
b: 20
}
const proxy = new Proxy(obj, {
set (target, properKey, value) {
// target[properKey] = value; // Reflect.set 重写
Reflect.set(target, properKey, value); // 尽量使用底层提供的方法
}
});
proxy.a = 100;
console.log(obj.a); //--> 100
虚拟DOM Vue 原理
<div id='demo'></div>
function observer(target = {}) {
const div = document.getElementById('demo');
const proxy = new Proxy(target, {
set(target, prop, value) {
Reflect.set(target, prop, value); // 没有ES6之前拿 Object.defineProperties 实现
render(); // 重新设置后渲染
},
get(target, prop) {
return Reflect.get(target, prop);
}
})
render(); // 初始化渲染
function render() { // 渲染到页面
let html = '';
for (const prop of Object.keys(proxy)) {
html += `<p><span>${prop}</span>:<span>${proxy[prop]}</span></p>`
}
div.innerHTML = html;
}
return proxy;
}
const obj = {
a: 1,
b: 2
}
let newObj = observer(obj);
newObj.a = 100;
函数代理
function validator(func, ...types) {
const proxy = new Proxy(func, {
apply(target, thisArgument, argumentsList) {
types.forEach((val, i) => {
const arg = argumentsList[i];
if (typeof arg !== val) {
throw new TypeError(`第${i + 1}个参数${argumentsList[i]}不满足类型${val}`)
}
})
return Reflect.apply(target, thisArgument, argumentsList);
}
})
return proxy;
}
function sum(a, b) {
return a + b;
}
const sumProxy = validator(sum, 'number', 'number');
console.log(sumProxy(3, 4)) //--> 7
动态属性
const add = new Proxy(
{
_store: 0,
},
{
get(target, prop, receiver) {
if (prop === Symbol.toPrimitive) {
return () => target._store;
}
target._store += +prop;
return receiver;
}
}
)
const num = add[1][2][5] + 10;
console.log(num); //--> 18